package kp.rpc.server.handler;

import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import kp.rpc.Enum.ProtocolMessageTypeEnum;
import kp.rpc.model.RpcRequest;
import kp.rpc.model.RpcResponse;
import kp.rpc.protocol.ProtocolMessage;
import kp.rpc.protocol.encode.ProtocolMessageDecoder;
import kp.rpc.protocol.encode.ProtocolMessageEncoder;
import kp.rpc.registry.LocalRegistry;
import kp.rpc.server.wrapper.TcpBufferHandlerWrapper;

import java.io.IOException;
import java.lang.reflect.Method;

public class TcpServerHandler implements Handler<NetSocket> {

    @Override
    public void handle(NetSocket netSocket) {
        // 使用bufferHandlerWrapper包装bufferHandler,做功能增强
        TcpBufferHandlerWrapper bufferHandlerWrapper = new TcpBufferHandlerWrapper(buffer -> {
            //接受请求,解码
            ProtocolMessage<RpcRequest> protocolMessage;
            try {
                protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decode(buffer);
            } catch (IOException e) {
                throw new RuntimeException("协议消息解码错误!");
            }
            RpcRequest rpcRequest = protocolMessage.getBody();
            //处理请求,构造响应结果对象
            RpcResponse rpcResponse = new RpcResponse();
            try {
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                //获取要调用的方法
                Method invokeMethod = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                //todo 后续有坑考虑这里
                Object invoke = invokeMethod.invoke(implClass.getDeclaredConstructor().newInstance(), rpcRequest.getArgs());
                //封装返回结果
                rpcResponse.setData(invoke);
                rpcResponse.setDataType(invokeMethod.getReturnType());
                rpcResponse.setMessage("ok");
            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setMessage(e.getMessage());
                rpcResponse.setException(e);
            }
            // 返回响应,编码
            ProtocolMessage.Header header = protocolMessage.getHeader();
            header.setType((byte) ProtocolMessageTypeEnum.RESPONSE.getKey());
            ProtocolMessage<RpcResponse> responseProtocolMessage = new ProtocolMessage<>(header, rpcResponse);
            //编码
            try {
                Buffer encodeBuffer = ProtocolMessageEncoder.encode(responseProtocolMessage);
                netSocket.write(encodeBuffer);
            } catch (IOException e) {
                throw new RuntimeException("协议消息编码错误!");
            }
        });
        // 异步处理 TCP 请求
        netSocket.handler(bufferHandlerWrapper);
    }
}
